package com.yunke.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunke.entity.YunkeCommunity;
import com.yunke.entity.YunkeCommunityMember;
import com.yunke.entity.dto.YunkeCommunityDto;
import com.yunke.entity.vo.YunkeCommunityMemberVo;
import com.yunke.entity.vo.YunkeCommunityPostVo;
import com.yunke.entity.vo.YunkeCommunityVo;
import com.yunke.common.exception.YunkeException;
import com.yunke.mapper.YunkeCommunityMapper;
import com.yunke.mapper.YunkeCommunityMemberMapper;
import com.yunke.mapper.YunkeCommunityPostMapper;
import com.yunke.service.YunkeCommunityService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 社群管理服务实现类
 * 
 * @author yunke
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class YunkeCommunityServiceImpl extends ServiceImpl<YunkeCommunityMapper, YunkeCommunity> implements YunkeCommunityService {

    private final YunkeCommunityMemberMapper communityMemberMapper;
    private final YunkeCommunityPostMapper communityPostMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createCommunity(YunkeCommunityDto dto, Long userId) {
        log.info("用户{}创建社群：{}", userId, dto.getCommunityName());
        
        // 检查用户是否已经创建过同名社群
        LambdaQueryWrapper<YunkeCommunity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(YunkeCommunity::getCreatorId, userId)
               .eq(YunkeCommunity::getCommunityName, dto.getCommunityName())
               .eq(YunkeCommunity::getStatus, 0);
        
        if (count(wrapper) > 0) {
            throw new YunkeException("您已经创建过同名社群");
        }
        
        // 创建社群
        YunkeCommunity community = new YunkeCommunity();
        BeanUtil.copyProperties(dto, community);
        community.setCreatorId(userId);
        community.setCurrentMembers(1);
        community.setSortWeight(0);
        community.setCommunityStatus(0);
        community.setAuditStatus(0);
        community.setIsTop(false);
        community.setIsRecommend(false);
        community.setStatus(0);
        community.setCreateTime(System.currentTimeMillis());
        community.setUpdateTime(System.currentTimeMillis());
        
        save(community);
        
        // 创建者自动成为群主
        YunkeCommunityMember member = new YunkeCommunityMember();
        member.setCommunityId(community.getId());
        member.setUserId(userId);
        member.setMemberRole(1); // 群主
        member.setMemberLevel(1);
        member.setMemberPoints(0);
        member.setJoinType(1);
        member.setMemberStatus(0);
        member.setIsTop(false);
        member.setStatus(0);
        member.setJoinTime(System.currentTimeMillis());
        member.setUpdateTime(System.currentTimeMillis());
        
        communityMemberMapper.insert(member);
        
        log.info("社群创建成功，ID：{}", community.getId());
        return community.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCommunity(YunkeCommunityDto dto, Long userId) {
        log.info("用户{}更新社群信息：{}", userId, dto.getId());
        
        YunkeCommunity community = getById(dto.getId());
        if (community == null) {
            throw new YunkeException("社群不存在");
        }
        
        // 检查权限：只有群主和管理员可以更新社群信息
        if (!checkCommunityPermission(dto.getId(), userId, 2)) {
            throw new YunkeException("无权限操作");
        }
        
        BeanUtil.copyProperties(dto, community, "id", "creatorId", "createTime");
        community.setUpdateTime(System.currentTimeMillis());
        
        return updateById(community);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteCommunity(Long communityId, Long userId) {
        log.info("用户{}删除社群：{}", userId, communityId);
        
        YunkeCommunity community = getById(communityId);
        if (community == null) {
            throw new YunkeException("社群不存在");
        }
        
        // 检查权限：只有群主可以删除社群
        if (!community.getCreatorId().equals(userId)) {
            throw new YunkeException("无权限操作");
        }
        
        // 软删除社群
        community.setStatus(1);
        community.setUpdateTime(System.currentTimeMillis());
        
        return updateById(community);
    }

    @Override
    public YunkeCommunityVo getCommunityDetail(Long communityId, Long userId) {
        return baseMapper.selectCommunityDetail(communityId, userId);
    }

    @Override
    public Page<YunkeCommunityVo> getCommunityPage(Integer current, Integer size, String keyword,
                                                   Integer communityType, Long categoryId, String region,
                                                   BigDecimal longitude, BigDecimal latitude, Integer distance, Long userId) {
        Page<YunkeCommunityVo> page = new Page<>(current, size);
        return baseMapper.selectCommunityPage(page, keyword, communityType, categoryId, region,
                                              longitude, latitude, distance, userId);
    }

    @Override
    public List<YunkeCommunityVo> getRecommendCommunities(Long userId, Integer limit) {
        return baseMapper.selectRecommendCommunities(userId, limit);
    }

    @Override
    public List<YunkeCommunityVo> getHotCommunities(Long userId, Integer limit) {
        return baseMapper.selectHotCommunities(userId, limit);
    }

    @Override
    public List<YunkeCommunityVo> getNearbyCommunities(BigDecimal longitude, BigDecimal latitude,
                                                        Integer distance, Long userId, Integer limit) {
        return baseMapper.selectNearbyCommunities(longitude, latitude, distance, userId, limit);
    }

    @Override
    public List<YunkeCommunityVo> getCommunitiesByCategory(Long categoryId, Long userId, Integer limit) {
        return baseMapper.selectCommunitiesByCategory(categoryId, userId, limit);
    }

    @Override
    public List<YunkeCommunityVo> searchCommunities(String keyword, Long userId, Integer limit) {
        return baseMapper.searchCommunities(keyword, userId, limit);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean joinCommunity(Long communityId, Long userId, String reason) {
        log.info("用户{}申请加入社群：{}", userId, communityId);
        
        YunkeCommunity community = getById(communityId);
        if (community == null) {
            throw new YunkeException("社群不存在");
        }
        
        // 检查是否已经是成员
        YunkeCommunityMember existMember = communityMemberMapper.selectMemberByUserIdAndCommunityId(userId, communityId);
        if (existMember != null) {
            throw new YunkeException("您已经是该社群成员");
        }
        
        // 检查成员数量限制
        if (community.getCurrentMembers() >= community.getMaxMembers()) {
            throw new YunkeException("社群人数已满");
        }
        
        // 创建成员记录
        YunkeCommunityMember member = new YunkeCommunityMember();
        member.setCommunityId(communityId);
        member.setUserId(userId);
        member.setMemberRole(3); // 普通成员
        member.setMemberLevel(1);
        member.setMemberPoints(0);
        member.setJoinType(1); // 申请加入
        member.setMemberStatus(0);
        member.setIsTop(false);
        member.setRemark(reason);
        member.setStatus(0);
        member.setJoinTime(System.currentTimeMillis());
        member.setUpdateTime(System.currentTimeMillis());
        
        communityMemberMapper.insert(member);
        
        // 更新社群成员数量
        baseMapper.updateMemberCount(communityId, 1);
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean leaveCommunity(Long communityId, Long userId) {
        log.info("用户{}退出社群：{}", userId, communityId);
        
        YunkeCommunityMember member = communityMemberMapper.selectMemberByUserIdAndCommunityId(userId, communityId);
        if (member == null) {
            throw new YunkeException("您不是该社群成员");
        }
        
        // 群主不能退出自己的社群
        if (member.getMemberRole() == 1) {
            throw new YunkeException("群主不能退出社群，请先转让群主权限");
        }
        
        // 删除成员记录
        member.setStatus(1);
        member.setUpdateTime(System.currentTimeMillis());
        communityMemberMapper.updateById(member);
        
        // 更新社群成员数量
        baseMapper.updateMemberCount(communityId, -1);
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean inviteUserToCommunity(Long communityId, Long userId, Long inviteUserId, String message) {
        log.info("用户{}邀请用户{}加入社群：{}", userId, inviteUserId, communityId);
        
        // 检查邀请权限
        if (!checkCommunityPermission(communityId, userId, 3)) {
            throw new YunkeException("无权限邀请用户");
        }
        
        // 检查被邀请用户是否已经是成员
        YunkeCommunityMember existMember = communityMemberMapper.selectMemberByUserIdAndCommunityId(inviteUserId, communityId);
        if (existMember != null) {
            throw new YunkeException("该用户已经是社群成员");
        }
        
        // TODO: 发送邀请通知
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeMemberFromCommunity(Long communityId, Long userId, Long memberId, String reason) {
        log.info("用户{}踢出成员{}，社群：{}", userId, memberId, communityId);
        
        // 检查权限：只有群主和管理员可以踢出成员
        if (!checkCommunityPermission(communityId, userId, 2)) {
            throw new YunkeException("无权限操作");
        }
        
        YunkeCommunityMember member = communityMemberMapper.selectMemberByUserIdAndCommunityId(memberId, communityId);
        if (member == null) {
            throw new YunkeException("用户不是该社群成员");
        }
        
        // 不能踢出群主
        if (member.getMemberRole() == 1) {
            throw new YunkeException("不能踢出群主");
        }
        
        // 管理员不能踢出其他管理员
        Integer userRole = communityMemberMapper.selectUserRoleInCommunity(userId, communityId);
        if (userRole == 2 && member.getMemberRole() == 2) {
            throw new YunkeException("管理员不能踢出其他管理员");
        }
        
        // 删除成员记录
        member.setStatus(1);
        member.setRemark(reason);
        member.setUpdateTime(System.currentTimeMillis());
        communityMemberMapper.updateById(member);
        
        // 更新社群成员数量
        baseMapper.updateMemberCount(communityId, -1);
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setMemberAsAdmin(Long communityId, Long userId, Long memberId) {
        log.info("用户{}设置用户{}为管理员，社群：{}", userId, memberId, communityId);
        
        // 检查权限：只有群主可以设置管理员
        if (!checkCommunityPermission(communityId, userId, 1)) {
            throw new YunkeException("无权限操作");
        }
        
        YunkeCommunityMember member = communityMemberMapper.selectMemberByUserIdAndCommunityId(memberId, communityId);
        if (member == null) {
            throw new YunkeException("用户不是该社群成员");
        }
        
        member.setMemberRole(2); // 管理员
        member.setUpdateTime(System.currentTimeMillis());
        
        return communityMemberMapper.updateById(member) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeMemberAsAdmin(Long communityId, Long userId, Long memberId) {
        log.info("用户{}取消用户{}的管理员权限，社群：{}", userId, memberId, communityId);
        
        // 检查权限：只有群主可以取消管理员
        if (!checkCommunityPermission(communityId, userId, 1)) {
            throw new YunkeException("无权限操作");
        }
        
        YunkeCommunityMember member = communityMemberMapper.selectMemberByUserIdAndCommunityId(memberId, communityId);
        if (member == null) {
            throw new YunkeException("用户不是该社群成员");
        }
        
        member.setMemberRole(3); // 普通成员
        member.setUpdateTime(System.currentTimeMillis());
        
        return communityMemberMapper.updateById(member) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean muteMember(Long communityId, Long userId, Long memberId, Long muteEndTime, String reason) {
        log.info("用户{}禁言用户{}，社群：{}，禁言到：{}", userId, memberId, communityId, muteEndTime);
        
        // 检查权限：只有群主和管理员可以禁言
        if (!checkCommunityPermission(communityId, userId, 2)) {
            throw new YunkeException("无权限操作");
        }
        
        YunkeCommunityMember member = communityMemberMapper.selectMemberByUserIdAndCommunityId(memberId, communityId);
        if (member == null) {
            throw new YunkeException("用户不是该社群成员");
        }
        
        // 不能禁言群主和管理员
        if (member.getMemberRole() <= 2) {
            throw new YunkeException("不能禁言群主和管理员");
        }
        
        member.setMemberStatus(1); // 禁言状态
        member.setMuteEndTime(muteEndTime);
        member.setRemark(reason);
        member.setUpdateTime(System.currentTimeMillis());
        
        return communityMemberMapper.updateById(member) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean unmuteMember(Long communityId, Long userId, Long memberId) {
        log.info("用户{}解除用户{}的禁言，社群：{}", userId, memberId, communityId);
        
        // 检查权限：只有群主和管理员可以解除禁言
        if (!checkCommunityPermission(communityId, userId, 2)) {
            throw new YunkeException("无权限操作");
        }
        
        YunkeCommunityMember member = communityMemberMapper.selectMemberByUserIdAndCommunityId(memberId, communityId);
        if (member == null) {
            throw new YunkeException("用户不是该社群成员");
        }
        
        member.setMemberStatus(0); // 正常状态
        member.setMuteEndTime(null);
        member.setUpdateTime(System.currentTimeMillis());
        
        return communityMemberMapper.updateById(member) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCommunityAnnouncement(Long communityId, Long userId, String announcement) {
        log.info("用户{}更新社群公告，社群：{}", userId, communityId);
        
        // 检查权限：只有群主和管理员可以更新公告
        if (!checkCommunityPermission(communityId, userId, 2)) {
            throw new YunkeException("无权限操作");
        }
        
        YunkeCommunity community = getById(communityId);
        if (community == null) {
            throw new YunkeException("社群不存在");
        }
        
        community.setAnnouncement(announcement);
        community.setUpdateTime(System.currentTimeMillis());
        
        return updateById(community);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCommunityRules(Long communityId, Long userId, String rules) {
        log.info("用户{}更新社群规则，社群：{}", userId, communityId);
        
        // 检查权限：只有群主和管理员可以更新规则
        if (!checkCommunityPermission(communityId, userId, 2)) {
            throw new YunkeException("无权限操作");
        }
        
        YunkeCommunity community = getById(communityId);
        if (community == null) {
            throw new YunkeException("社群不存在");
        }
        
        community.setRules(rules);
        community.setUpdateTime(System.currentTimeMillis());
        
        return updateById(community);
    }

    @Override
    public Page<YunkeCommunityMemberVo> getCommunityMembers(Long communityId, Integer current, Integer size,
                                                            Integer memberRole, String keyword, Long userId) {
        Page<YunkeCommunityMemberVo> page = new Page<>(current, size);
        return communityMemberMapper.selectMemberPage(page, communityId, memberRole, keyword);
    }

    @Override
    public Page<YunkeCommunityPostVo> getCommunityPosts(Long communityId, Integer current, Integer size,
                                                        Integer postType, Boolean isTop, Boolean isEssence, Long userId) {
        Page<YunkeCommunityPostVo> page = new Page<>(current, size);
        return communityPostMapper.selectPostPage(page, communityId, postType, isTop, isEssence, userId);
    }

    @Override
    public List<YunkeCommunityVo> getUserCreatedCommunities(Long userId) {
        return baseMapper.selectUserCreatedCommunities(userId);
    }

    @Override
    public List<YunkeCommunityVo> getUserJoinedCommunities(Long userId) {
        return baseMapper.selectUserJoinedCommunities(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean transferCommunityOwnership(Long communityId, Long userId, Long newOwnerId) {
        log.info("用户{}转让社群{}的群主权限给用户{}", userId, communityId, newOwnerId);
        
        // 检查权限：只有群主可以转让
        if (!checkCommunityPermission(communityId, userId, 1)) {
            throw new YunkeException("无权限操作");
        }
        
        // 检查新群主是否为社群成员
        YunkeCommunityMember newOwnerMember = communityMemberMapper.selectMemberByUserIdAndCommunityId(newOwnerId, communityId);
        if (newOwnerMember == null) {
            throw new YunkeException("新群主必须是社群成员");
        }
        
        // 更新社群创建者
        YunkeCommunity community = getById(communityId);
        community.setCreatorId(newOwnerId);
        community.setUpdateTime(System.currentTimeMillis());
        updateById(community);
        
        // 更新原群主为普通成员
        YunkeCommunityMember oldOwnerMember = communityMemberMapper.selectMemberByUserIdAndCommunityId(userId, communityId);
        oldOwnerMember.setMemberRole(3);
        oldOwnerMember.setUpdateTime(System.currentTimeMillis());
        communityMemberMapper.updateById(oldOwnerMember);
        
        // 更新新群主为群主
        newOwnerMember.setMemberRole(1);
        newOwnerMember.setUpdateTime(System.currentTimeMillis());
        communityMemberMapper.updateById(newOwnerMember);
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean dissolveCommunity(Long communityId, Long userId) {
        log.info("用户{}解散社群：{}", userId, communityId);
        
        // 检查权限：只有群主可以解散社群
        if (!checkCommunityPermission(communityId, userId, 1)) {
            throw new YunkeException("无权限操作");
        }
        
        // 更新社群状态为解散
        YunkeCommunity community = getById(communityId);
        community.setCommunityStatus(2); // 解散状态
        community.setUpdateTime(System.currentTimeMillis());
        updateById(community);
        
        // 删除所有成员
        communityMemberMapper.deleteAllMembersByCommunityId(communityId);
        
        // 删除所有动态
        communityPostMapper.deleteAllPostsByCommunityId(communityId);
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean topCommunity(Long communityId, Long adminId, Long topEndTime) {
        log.info("管理员{}置顶社群：{}，到期时间：{}", adminId, communityId, topEndTime);
        
        YunkeCommunity community = getById(communityId);
        if (community == null) {
            throw new YunkeException("社群不存在");
        }
        
        community.setIsTop(true);
        community.setTopEndTime(topEndTime);
        community.setUpdateTime(System.currentTimeMillis());
        
        return updateById(community);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelTopCommunity(Long communityId, Long adminId) {
        log.info("管理员{}取消置顶社群：{}", adminId, communityId);
        
        YunkeCommunity community = getById(communityId);
        if (community == null) {
            throw new YunkeException("社群不存在");
        }
        
        community.setIsTop(false);
        community.setTopEndTime(null);
        community.setUpdateTime(System.currentTimeMillis());
        
        return updateById(community);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean auditCommunity(Long communityId, Long adminId, Integer auditStatus, String auditRemark) {
        log.info("管理员{}审核社群：{}，状态：{}", adminId, communityId, auditStatus);
        
        YunkeCommunity community = getById(communityId);
        if (community == null) {
            throw new YunkeException("社群不存在");
        }
        
        community.setAuditStatus(auditStatus);
        community.setAuditRemark(auditRemark);
        community.setAuditTime(System.currentTimeMillis());
        community.setUpdateTime(System.currentTimeMillis());
        
        return updateById(community);
    }

    @Override
    public YunkeCommunityVo getCommunityStats(Long communityId) {
        return baseMapper.selectCommunityStats(communityId);
    }

    /**
     * 检查社群权限
     * @param communityId 社群ID
     * @param userId 用户ID
     * @param minRole 最小权限等级（1群主 2管理员 3普通成员）
     * @return 是否有权限
     */
    private boolean checkCommunityPermission(Long communityId, Long userId, Integer minRole) {
        Integer userRole = communityMemberMapper.selectUserRoleInCommunity(userId, communityId);
        return userRole != null && userRole <= minRole;
    }
} 